Navidrome IIS Reverse Proxy
2026-01-02 09:24
This is a quick post, not a full How To.
BLUF
To use IIS as your reverse proxy for Navidrome: a) enable WebSockets, and b) clear theAccept-Encodingheader's value
I recently replaced my long-running (and woefully unmaintained) Subsonic self-hosted music server with Navidrome. This was initially (relatively) painless, as Navidrome has:
- A native Windows installer that also installs a Windows Service
- Straightforward ability to point to my existing library
- Reasonably easy to import playlists I exported from Subsonic
There were a few barriers.
- The documentation didn't seem as clear as I'd have liked on how configuration options work. Specifically, that options can be set in the
navidrome.inifile OR server environment variables, and that the option names are not the same. But, in fairness, this was probably me being impatient. - Navidrome organizes songs completely based on tags. This makes sense, but initially showed lots of my albums as separate songs. It was tedious (but worthwhile) to tag those songs to include Album Artist. The tagging guidelines documentation is very useful here . . .
- Except, that in some cases the Year tag is what would cause albums to show separately. I'm pretty sure this has more to do with a bunch of MP4 (.m4a) files I have. Someday I'd like to convert those to MP3 and then reget the album info.
- My previous Subsonice reverse proxy didn't work with Navidrome.
The last one is the subject of this post. I lost about eight hours on it. The reason to use a reverse proxy is because the Navidrome application (web server) doesn't support SSL. But, if using the app publically (not just within one's local network), SSL (HTTPS) is essential for security. Most of the web examples of using a reverse proxy with Navidrome use nginx. I came very close to installing and using nginx, but that would have required me switching all of my other sites to use it to. Ugh.
I use Microsoft Internet Information Server (IIS) on purpose; I'm a Microsoft stack developer, and need to understand the tools. And it seemed like it should work. But I kept getting an HTTP 500 error.
Finally, after looking at logs and beating my head against the keyboard (didn't help), I installed Fiddler Classic to watch the traffic. It didn't tell me more than I knew, but then I tried sending my GET request from Fiddler.
And it worked.
Fiddler Compose, by default, only uses two headers. This led to a process of elimination of the headers being sent. Fiddler made this pretty easy since I could copy the headers I sent from my browser request (examinging Fiddler Inspection) directly into the Fiddler Compose, eliminating them until it worked again. It turned out, the Navidrome app's web server doesn't accept encoding (or at least not standard encoding).
Once I knew that, I could update IIS Url Rewrite to include the server variables (not at all well documented how those relate to HTTP headers) and change their values.
Sorry, you'll need to do your own research on configuring IIS as a reverse proxy. There may be a better way than what I've done (because I'm still finding different documentation on how to do it).
Here's the web.config I used. It:
- Passes requests from
https://music.flattland.comto Navidrome - Changes the Accept-Encoding request header via a server variable
- Allows (somehow) WebSockets passthrough
- Rewrites outbound URL tag values if the Navidrome URL
http://localhost:4533is found
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:4533/{R:1}" />
<serverVariables>
<set name="HTTP_SEC_WEBSOCKET_EXTENSIONS" value="" />
<set name="HTTP_ACCEPT_ENCODING" value="" />
<set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://localhost:4533/(.*)" />
<action type="Rewrite" value="http{R:1}://music.flattland.com/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression doStaticCompression="true" />
</system.webServer>
</configuration>
References
Some of these I didn't use, but may still be helpful, especially if you're trying to mimic nginx.
- HOWTO: Configure IIS as a Reverse Proxy for the Integrated Web Server
- This site says to enable "preserveHostHeader," which I didn't do. Maybe that would remove the need to overwrite Accept-Encoding?
- Setting HTTP request headers and IIS server variables
- Official MS documentation. It confusingly does two things: changes language mapping and overwrites HTTP headers via server variables
- How to set the X-Forwarded-For header on IIS reverse proxy setup?
- I didn't need to do this, but nginx shows it.
- Setting up Navidrome with Nginx as a reverse proxy